package com.cqhfan.chatroom.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.cqhfan.chatroom.domain.dto.CreateChatGroupDTO;
import com.cqhfan.chatroom.domain.po.ChatGroup;
import com.cqhfan.chatroom.domain.po.ChatGroupUser;
import com.cqhfan.chatroom.domain.po.ChatList;
import com.cqhfan.chatroom.domain.po.User;
import com.cqhfan.chatroom.domain.vo.ChatGroupInfoVO;
import com.cqhfan.chatroom.domain.vo.ChatGroupVO;
import com.cqhfan.chatroom.domain.vo.GroupMemberVO;
import com.cqhfan.chatroom.enums.ChatType;
import com.cqhfan.chatroom.mapper.ChatGroupMapper;
import com.cqhfan.chatroom.mapper.UserMapper;
import com.cqhfan.chatroom.service.IChatGroupService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqhfan.chatroom.service.IChatGroupUserService;
import com.cqhfan.chatroom.service.IChatListService;
import com.cqhfan.common.constants.RedisConstants;
import com.cqhfan.common.exceptions.BizException;
import com.cqhfan.common.utils.UserContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 群表 服务实现类
 * </p>
 *
 * @author 眭传洪
 * @since 2024-11-20
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ChatGroupServiceImpl extends ServiceImpl<ChatGroupMapper, ChatGroup> implements IChatGroupService {

    private final IChatGroupUserService chatGroupUserService;

    private final StringRedisTemplate stringRedisTemplate;

    private final IChatListService chatListService;

    private final UserMapper userMapper;

    @Override
    @Transactional
    public Long createChatGroupInfo(CreateChatGroupDTO body) {
        Long userId = UserContext.getUser();
        List<Long> memberIds = body.getMemberIds();
        memberIds.add(userId);

        // 查询用户信息
        List<User> users = userMapper.selectBatchIds(memberIds);
        Map<Long, String> userMap = users.stream().collect(Collectors.toMap(User::getId, User::getNickname));

        // 创建群聊信息
        ChatGroup chatGroup = new ChatGroup();
        chatGroup.setGroupName(body.getGroupName());
        chatGroup.setGroupLeaderId(userId);
        chatGroup.setGroupAvatar(body.getGroupAvatar());
        chatGroup.setTotal(memberIds.size());
        chatGroup.setCreateTime(LocalDateTime.now());
        save(chatGroup);
        Long groupId = chatGroup.getId();

        // 创建群成员信息
        List<ChatGroupUser> chatGroupUsers = memberIds.stream().map(item -> {
            ChatGroupUser chatGroupUser = new ChatGroupUser();
            chatGroupUser.setUserId(item);
            chatGroupUser.setGroupId(groupId);
            chatGroupUser.setRemark(userMap.get(item));
            chatGroupUser.setCreateTime(LocalDateTime.now());
            return chatGroupUser;
        }).toList();
        chatGroupUserService.saveBatch(chatGroupUsers);

        // 创建聊天列表信息
        List<ChatList> chatLists = chatGroupUsers.stream().map(item -> {
            ChatList chatList = new ChatList();
            chatList.setType(ChatType.MULTI);
            chatList.setGroupId(groupId);
            chatList.setUserId(item.getUserId());
            chatList.setCreateTime(LocalDateTime.now());
            return chatList;
        }).toList();
        chatListService.saveBatch(chatLists);

        // 将群成员存到redis
        String key = RedisConstants.GROUP_MEMBERS_KEY_PREFIX + groupId;
        stringRedisTemplate.opsForSet().add(key, memberIds.stream().map(String::valueOf).toList().toArray(new String[0]));

        return groupId;
    }

    @Override
    public List<ChatGroupVO> listMyChatGroup() {
        Long userId = UserContext.getUser();
        // 查询我的群聊信息
        List<ChatGroup> chatGroups = lambdaQuery().eq(ChatGroup::getGroupLeaderId, userId).list();
        if (CollUtil.isEmpty(chatGroups)) {
            return Collections.emptyList();
        }

        // 组装vo
        List<ChatGroupVO> result = new ArrayList<>(chatGroups.size());
        for (ChatGroup chatGroup : chatGroups) {
            ChatGroupVO vo = new ChatGroupVO();
            vo.setId(chatGroup.getId());
            vo.setGroupName(chatGroup.getGroupName());
            vo.setGroupAvatar(chatGroup.getGroupAvatar());
            result.add(vo);
        }

        return result;
    }

    @Override
    public ChatGroupInfoVO getChatGroupInfo(Long groupId) {
        // 查询群聊信息
        ChatGroup chatGroup = getById(groupId);
        if (chatGroup == null) {
            throw new BizException("群聊信息为空");
        }

        // 查询群的人员信息
        List<ChatGroupUser> groupUsers = chatGroupUserService.lambdaQuery().eq(ChatGroupUser::getGroupId, groupId).list();
        if (CollUtil.isEmpty(groupUsers)) {
            throw new BizException("群成员为空， groupId: " + groupId);
        }

        // 拿到用户信息
        List<Long> userIds = groupUsers.stream().map(ChatGroupUser::getUserId).toList();
        List<User> users = userMapper.selectBatchIds(userIds);
        Map<Long, String> userAvatarMap = users.stream().collect(Collectors.toMap(User::getId, User::getAvatar));

        // 组装vo
        ChatGroupInfoVO result = new ChatGroupInfoVO();
        result.setId(groupId);
        result.setGroupName(chatGroup.getGroupName());
        result.setGroupAvatar(chatGroup.getGroupAvatar());
        result.setTotal(chatGroup.getTotal());
        List<GroupMemberVO> members = new ArrayList<>(groupUsers.size());
        for (ChatGroupUser groupUser : groupUsers) {
            Long userId = groupUser.getUserId();
            GroupMemberVO vo = new GroupMemberVO();
            vo.setId(userId);
            vo.setRemark(groupUser.getRemark());
            vo.setAvatar(userAvatarMap.get(userId));
            members.add(vo);
        }
        result.setMembers(members);
        return result;
    }
}
